package com.cskaoyan.javase.oop2._1extends._8hidden._0introduction;

/**
 * 属性的隐藏
 * 父子类的成员是允许同名的。
 * 那么如果父子类属性同名了，那么不使用super区分，直接访问的效果是什么样的呢？
 * 直接创建子类对象用子类引用接收,访问同名成员变量,结果是子类中的取值.
 * 那么这个现象怎么理解?
 * 子类成员和父类成员变量有各自的存储区域,所以不可能是被覆盖掉了
 * 而是由于"对象名点"访问成员变量的机制原因,被隐藏了,这就是属性的隐藏.
 *
 * 接下来研究"对象名点"访问成员变量的访问机制,以及结果
 * 存在继承以后,在继承体系中,创建对象"对象名的来源"的方式有以下:
 *      1.子类引用指向子类对象
 *      2.父类引用指向父类对象
 *      3.父类引用指向子类对象
 *
 * "对象名点"访问成员变量的访问机制,从以下两个角度研究:
 *      1.访问的范围
 *      2.访问的结果
 *
 * 首先看"访问范围"
 * 1.子类引用指向子类对象
 *      访问范围是 "父类 + 子类"
 *
 * 2.父类引用指向父类对象
 *      访问范围只有父类
 *
 * 3.父类引用指向子类对象
 *      访问范围只有父类
 *
 * 以上总结,对象名点成员变量,访问范围只要看引用的数据类型即可
 *      如果引用是父类类型,那就只能访问父类中存在的成员变量
 *      如果引用是子类类型,那就能访问 父类 + 子类
 *
 * 接下来研究对象名点成员变量的访问结果:
 * 1.子类引用指向子类对象
 *      结果是子类中的变量结果
 *
 * 2.父类引用指向父类对象
 *      结果是父类中变量的结果
 *
 * 3.父类引用指向子类对象
 *      结果是父类中变量的结果
 *
 * 以上总结,"对象名点"访问成员变量的访问机制非常简单
 * 就只看引用就够了
 * 无论是访问范围,还是访问的结果,都是根据引用来确定的
 *
 *
 * @since 09:31
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*Son s = new Son();
        System.out.println(s.num);
        System.out.println(s.getNum());*/

        // 1.子类引用指向子类对象
        Son s = new Son();
        System.out.println(s.num);
        // System.out.println(s.fatherVar);
        // System.out.println(s.sonVar);

        // 2.父类引用指向父类对象
        Father f = new Father();
        System.out.println(f.num);
        // System.out.println(f.fatherVar);
        // f.son

        // 3.父类引用指向子类对象
        Father fs = new Son();
        // System.out.println(fs.fatherVar);
        System.out.println(fs.num);
        // fs.sonVar
    }
}

class Father {
    int num = 10;
    int fatherVar = 100;

    /*public int getNum() {
        return num;
    }*/
}

class Son extends Father {
    int num = 20;
    int sonVar = 200;
}